package com.zhangzc.sc.scquery.Esconfig;

import lombok.Setter;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.elasticsearch.client.Node;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.URI;
import java.util.Arrays;
import java.util.Objects;


@Configuration
@ConfigurationProperties(prefix = "es")
@Setter
public class ElasticsearchConfig {

    private String[] uris;

    private Integer connectionTimeout;

    private Integer socketTimeout;

    private Integer connectTimeout;
 
    @Bean
    public RestClientBuilder restClientBuilder() {
        HttpHost[] hosts = Arrays.stream(uris)
                .map(this::parseAddress)
                .filter(Objects::nonNull)
                .toArray(HttpHost[]::new);
        RestClientBuilder restClientBuilder = RestClient.builder(hosts);
        // 设置一个监听器，每次节点出现故障时都会收到通知，以防需要采取措施，
        // 当启用故障嗅探时在内部使用。
        restClientBuilder.setFailureListener(new RestClient.FailureListener() {
            @Override
            public void onFailure(Node node) {
 
            }
        });
        // 设置允许修改默认请求配置的回调
        //（例如请求超时，身份验证或org.apache.http.client.config.RequestConfig.Builder允许设置的任何内容）。
        restClientBuilder.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
            @Override
            public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {
                return requestConfigBuilder
                        .setConnectionRequestTimeout(connectionTimeout)
                        .setSocketTimeout(socketTimeout)
                        .setConnectTimeout(connectTimeout);
            }
        });
        return restClientBuilder;
    }
 
    @Bean(name = "highLevelClient")
    public RestHighLevelClient highLevelClient(@Autowired RestClientBuilder restClientBuilder) {
        // TODO 此处可以进行其它操作
        return new RestHighLevelClient(restClientBuilder);
    }

    /**
     * 解析 Elasticsearch 地址（支持格式）：
     * 1. "http:127.0.0.1:9200"
     * 2. "127.0.0.1:9200"（默认 HTTP）
     * 3. "https://example.com:9200"（标准 URL）
     */
    public HttpHost parseAddress(String address) {
        if (address == null || address.trim().isEmpty()) {
            throw new IllegalArgumentException("Address cannot be null or empty");
        }
        try {
            // 处理 "http:IP:端口" 格式
            if (address.startsWith("http:") && !address.startsWith("http://")) {
                address = address.replaceFirst("http:", "http://");
            } else if (address.startsWith("https:") && !address.startsWith("https://")) {
                address = address.replaceFirst("https:", "https://");
            }
            // 统一转换为 URI 解析
            URI uri = new URI(address);
            String scheme = uri.getScheme() != null ? uri.getScheme() : "http";
            String host = uri.getHost();
            int port = uri.getPort();
            if (host == null) {
                // 处理无协议的情况（如 "127.0.0.1:9200"）
                String[] parts = address.split(":");
                if (parts.length >= 2) {
                    host = parts[0];
                    port = Integer.parseInt(parts[1]);
                } else {
                    throw new IllegalArgumentException("Invalid address format: " + address);
                }
            }
            if (port == -1) {
                port = 9200; // 默认端口
            }
            return new HttpHost(host, port, scheme);
        } catch (Exception e) {
            throw new IllegalArgumentException("Failed to parse address: " + address, e);
        }
    }
 
}
